package com.ys.service.sys.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bo.vo.R;
import com.ys.dto.AddDto;
import com.ys.dto.DtreeSqlDto;
import com.ys.dto.EditDto;
import com.ys.entity.sys.TsRoleInfo;
import com.ys.entity.sys.YsButton;
import com.ys.entity.sys.YsMenu;
import com.ys.entity.sys.YsRole;
import com.ys.entity.sys.YsRoleButton;
import com.ys.entity.sys.YsRoleMenu;
import com.ys.enume.sys.YsMenuEnum;
import com.ys.enume.sys.YsRoleEnum;
import com.ys.enume.sys.YsRoleMenuEnum;
import com.ys.mapper.business.DiySqlMapper;
import com.ys.mapper.sys.TsRoleInfoMapper;
import com.ys.mapper.sys.YsRoleButtonMapper;
import com.ys.mapper.sys.YsRoleMapper;
import com.ys.mapper.sys.YsRoleMenuMapper;
import com.ys.service.sys.YsRoleService;
import com.ys.util.RandomUtil;
import com.ys.vo.W;

@Service("ysRoleService")
public class YsRoleServiceImpl implements YsRoleService {
	@Autowired
	private DiySqlMapper diySqlMapper;
	@Autowired
	private TsRoleInfoMapper tsRoleInfoMapper;
	@Autowired
	private YsRoleMapper ysRoleMapper;
	@Autowired
	private YsRoleMenuMapper ysRoleMenuMapper;
	@Autowired
	private YsRoleButtonMapper ysRoleButtonMapper;
	
	@Override
	public R add(Map<String, Object> params) {
		
		YsRole entity = JSON.parseObject(JSON.toJSONString(params), YsRole.class);
		entity.setPid(1L);
		
		
		if (entity.getType() == null) {
			return R.error("权限不能为空");
		}
		
		ysRoleMapper.insert(entity);
		
		// 旧系统添加角色数据
		TsRoleInfo tsRoleInfo = null;
		{
			String guid = RandomUtil.getGUID();
			String roleName = entity.getName();
			String roleDataLimit = YsRoleEnum.Type.getValueOld(entity.getType());
			Integer roleOrder = 1;
			Integer deleted = 0;
			String createUser = null;
			String updateUser = null;
			String pageTemplate = "通用首页";
			Integer remindDaysForContract = null;
			String vGwZz = null;
			tsRoleInfo = TsRoleInfo.tsRoleInfo(
					guid, roleName, roleDataLimit, roleOrder, deleted,
					createUser, updateUser, pageTemplate, remindDaysForContract, vGwZz, 1);
			tsRoleInfoMapper.insert(tsRoleInfo);
		}
		return R.ok(AddDto.closeAndReload());
	}
	
	@Override
	@Transactional
	public R edit(Long id, Map<String, Object> params) {
		YsRole oldRole = new YsRole().setId(id).queryFirst();

		YsRole entity = JSON.parseObject(JSON.toJSONString(params), YsRole.class);
		ysRoleMapper.update(entity);
		
		TsRoleInfo tsRoleInfo = new TsRoleInfo().setRoleName(oldRole.getName()).queryFirst();
		tsRoleInfo.setRoleName(entity.getName())
			.setRoleDataLimit(YsRoleEnum.Type.getValueOld(entity.getType()));
		tsRoleInfoMapper.update(tsRoleInfo);
		
		return R.ok(EditDto.closeAndReload());
	}

	@Override
	public String toAuth(Model model, Long roleId) {
		
		if (roleId == 1) {
			return W.error(model, "顶级账号无需授权");
		}
		
		ToAuthDto dto = new ToAuthDto(roleId);
		model.addAttribute("dto", dto);
		return "sys/ysRole/toAuth";
	}

	@Override
	public DtreeSqlDto dtreeForAuth(Long roleId) {
		
		DtreeSqlDto.StatusDto status = DtreeSqlDto.StatusDto.init(200, "");
		

		// 查询所有的一级菜单，用于遍历
		List<YsMenu> listYsMenu = new YsMenu()
				.setOrderby("A.Lev asc, A.SortNo asc")
				.queryList();
		// 查询角色所有的授权菜单
		List<YsRoleMenu> listYsRoleMenu = new YsRoleMenu()
				.setRoleId(roleId).queryList();
		List<Long> listMenuIdOwn = new ArrayList<Long>();
		for(YsRoleMenu ysRoleMenu : listYsRoleMenu) {
			listMenuIdOwn.add(ysRoleMenu.getMenuId());
		}
		
		List<DtreeSqlDto.DataDto> data = new ArrayList<DtreeSqlDto.DataDto>();
		for(YsMenu ysMenu1 : listYsMenu) {
			
			if (ysMenu1.getLev() != YsMenuEnum.Lev.ONE.value) {
				continue;
			}
			
			List<DtreeSqlDto.DataDto> children1 = new ArrayList<DtreeSqlDto.DataDto>();
			for(YsMenu ysMenu2 : listYsMenu) {
				if (ysMenu2.getPid().longValue() != ysMenu1.getId().longValue()) {
					continue;
				}
				List<DtreeSqlDto.DataDto> children2 = new ArrayList<DtreeSqlDto.DataDto>();
				for(YsMenu ysMenu3 : listYsMenu) {
					if (ysMenu3.getPid().longValue() != ysMenu2.getId().longValue()) {
						continue;
					}
					List<DtreeSqlDto.DataDto> childrenOfModule = new ArrayList<DtreeSqlDto.DataDto>();
					Integer checked = listMenuIdOwn.contains(ysMenu3.getId()) ? 1 : 0;
					children2.add(new DtreeSqlDto.DataDto(ysMenu3.getId().toString(), ysMenu3.getName(), ysMenu3.getPid().toString(),
							DtreeSqlDto.DataDto.initCheckArr(checked), childrenOfModule));
				}
				Integer checked = listMenuIdOwn.contains(ysMenu2.getId()) ? 1 : 0;
				children1.add(new DtreeSqlDto.DataDto(ysMenu2.getId().toString(), ysMenu2.getName(), ysMenu2.getPid().toString(),
						DtreeSqlDto.DataDto.initCheckArr(checked), children2));
			}
			Integer checked = listMenuIdOwn.contains(ysMenu1.getId()) ? 1 : 0;
			data.add(new DtreeSqlDto.DataDto(ysMenu1.getId().toString(), ysMenu1.getName(), null, DtreeSqlDto.DataDto.initCheckArr(checked), children1));
		}
		DtreeSqlDto dto = new DtreeSqlDto(status, data);
		return dto;
	}

	@Override
	public R listForAuth(Long roleId, Long menuId) {
		
		// 查询对应的功能模块
		YsMenu cond = new YsMenu().setLev(YsMenuEnum.Lev.THREE.value);
		if (menuId != null) {
			YsMenu ysMenu = new YsMenu().setId(menuId).queryFirst();
			if (ysMenu.getLev() == YsMenuEnum.Lev.ONE.value) {
				cond.addLeftJoin("YS_Menu B on B.Id = A.Pid")
					.where("B.Pid = " + menuId);
			} else if (ysMenu.getLev() == YsMenuEnum.Lev.TWO.value) {
				cond.setPid(menuId);
			} else {
				cond.setId(menuId);
			}
		}
		List<YsMenu> listYsMenu = cond.setOrderby("A.Lev asc, A.SortNo asc").queryList();
		// 查询角色所有的授权菜单
		List<YsRoleMenu> listYsRoleMenu = new YsRoleMenu()
				.setRoleId(roleId).queryList();
		Map<Long, YsRoleMenu> MAP_MENUID_ROLEMENU = new HashMap<Long, YsRoleMenu>();
		for(YsRoleMenu ysRoleMenu : listYsRoleMenu) {
			MAP_MENUID_ROLEMENU.put(ysRoleMenu.getMenuId(), ysRoleMenu);
		}
		
		// 查询所有的按钮，用于遍历
		List<YsButton> listYsButton = new YsButton().queryList();
		// 查询角色所有的按钮
		List<YsRoleButton> listYsRoleButton = new YsRoleButton().setRoleId(roleId).queryList();
		List<Long> listButtonId = new ArrayList<Long>();
		for(YsRoleButton ysRoleButton : listYsRoleButton) {
			listButtonId.add(ysRoleButton.getButtonId());
		}
		
		List<ToListForAuthDto.MenuDto> menuArr = new ArrayList<ToListForAuthDto.MenuDto>();
		for(YsMenu ysMenu : listYsMenu) {
			
			List<ToListForAuthDto.MenuDto.ButtonDto> buttonArr = new ArrayList<ToListForAuthDto.MenuDto.ButtonDto>();
			for(YsButton ysButton : listYsButton) {
				if (ysButton.getMenuId().longValue() != ysMenu.getId().longValue()) {
					continue;
				}
				Long id = ysButton.getId();
				String name = ysButton.getName();
				boolean isSelected = listButtonId.contains(id);
				buttonArr.add(new ToListForAuthDto.MenuDto.ButtonDto(id, name, isSelected));
			}
			
			YsRoleMenu ysRoleMenu = MAP_MENUID_ROLEMENU.get(ysMenu.getId());
			
			Long id = ysMenu.getId();
			String name = ysMenu.getName();
			boolean isSelected = MAP_MENUID_ROLEMENU.containsKey(id);
			Integer type = ysRoleMenu != null ? ysRoleMenu.getType() : YsRoleMenuEnum.Type.ALL.value;
			menuArr.add(new ToListForAuthDto.MenuDto(id, name, isSelected, buttonArr, type));
		}
		ToListForAuthDto dto = new ToListForAuthDto(menuArr);
		return R.ok(dto);
	}

	@Override
	public R saveAuth(Long roleId, String menuArr) {
		if (roleId == null) {
			return R.error("角色ID不能为空");
		}
		
		System.out.println(menuArr);
		
		JSONArray menuJA = JSON.parseArray(menuArr);
		for (int i = 0; i < menuJA.size(); i++) {
			JSONObject menuJO = menuJA.getJSONObject(i);
			Long menuId = menuJO.getLong("id");
			diySqlMapper.deleteYsRoleMenuByRoleIdAndMenuId(roleId, menuId);

			if (menuJO.getBoolean("selected") == true) {
				Integer type = menuJO.getInteger("type");
				YsRoleMenu ysRoleMenu = YsRoleMenu.ysRoleMenu(roleId, menuId, type, 1);
				ysRoleMenuMapper.insert(ysRoleMenu);
				
				JSONArray buttonJA = menuJO.getJSONArray("buttonArr");
				for (int j = 0; j < buttonJA.size(); j++) {
					JSONObject buttonJO = buttonJA.getJSONObject(j);
					Long buttonId = buttonJO.getLong("id");
					diySqlMapper.deleteYsRoleButtonByRoleIdAndButtonId(roleId, buttonId);
					
					if (buttonJO.getBoolean("selected") == true) {
						YsRoleButton ysRoleButton = YsRoleButton.ysRoleButton(roleId, buttonId, 1);
						ysRoleButtonMapper.insert(ysRoleButton);
					}
				}
			}
		}
		
		return R.ok();
	}

	@Override
	public R addRoleMenu(Long roleId, Long menuId, Integer type) {
		if (new YsRoleMenu().setRoleId(roleId).setMenuId(menuId).count() > 0) {
			return R.ok();
		}
		
		if (YsRoleMenuEnum.Type.checkIn(type) == false) {
			return R.error("请选择权限类型");
		}
		
		YsRoleMenu roleMenu = YsRoleMenu.ysRoleMenu(roleId, menuId, type, 1);
		ysRoleMenuMapper.insert(roleMenu);
		return R.ok();
	}

	@Override
	public R cancelRoleMenu(Long roleId, Long menuId) {
		
		YsRoleMenu entity = new YsRoleMenu().setRoleId(roleId).setMenuId(menuId).queryFirst();
		if (entity == null) {
			return R.error("不存在授权信息，无法取消");
		}
		
		ysRoleMenuMapper.deleteTrue(entity.getId());
		return R.ok();
	}

	@Override
	public R changeAuthMenuType(Long roleId, Long menuId, Integer type) {
		YsRoleMenu entity = new YsRoleMenu().setRoleId(roleId).setMenuId(menuId).queryFirst();
		if (entity == null) {
			return R.error("尚未授权该菜单");
		}
		
		entity.setType(type);
		ysRoleMenuMapper.update(entity);
		return R.ok("修改成功");
	}

	@Override
	public R addRoleButton(Long roleId, Long buttonId) {
		if (new YsRoleButton().setRoleId(roleId).setButtonId(buttonId).count() > 0) {
			return R.ok();
		}
		
		YsRoleButton ysRoleButton = YsRoleButton.ysRoleButton(roleId, buttonId, 1);
		ysRoleButtonMapper.insert(ysRoleButton);
		return R.ok();
	}

	@Override
	public R cancelRoleButton(Long roleId, Long buttonId) {
		
		YsRoleButton entity = new YsRoleButton().setRoleId(roleId).setButtonId(buttonId).queryFirst();
		if (entity == null) {
			return R.error("不存在授权信息，无法取消");
		}
		
		ysRoleButtonMapper.deleteTrue(entity.getId());
		return R.ok();
	}
	
}
